package org.jsola.hr.service.impl;

import org.jsola.core.Page;
import org.jsola.core.entity.BaseDO;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IEmpRewardPunishDAO;
import org.jsola.hr.dto.EmpRewardPunishAddDTO;
import org.jsola.hr.dto.EmpRewardPunishDTO;
import org.jsola.hr.dto.EmpRewardPunishUpdateDTO;
import org.jsola.hr.entity.EmpRewardPunishDO;
import org.jsola.hr.query.EmpRewardPunishQuery;
import org.jsola.hr.service.IEmpRewardPunishService;
import org.jsola.hr.vo.EmpRewardPunishListVO;
import org.jsola.hr.vo.EmpRewardPunishVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 员工奖惩记录
 *
 * @author zhr
 */
@Service("hrEmpRewardPunishServiceImpl")
public class EmpRewardPunishServiceImpl implements IEmpRewardPunishService {

    @Autowired
    private IEmpRewardPunishDAO empRewardPunishDAO;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpRewardPunishVO save(EmpRewardPunishAddDTO empRewardPunishAddDTO, TokenUser tokenUser) {
        // 转DO
        EmpRewardPunishDO empRewardPunishDO = empRewardPunishAddDTO.to(EmpRewardPunishDO.class);

        // 校验员工和公司
        checkEmpAndCompany(empRewardPunishDO.getEmpId(), empRewardPunishDO.getCompanyId(), tokenUser.getSiteId());

        // 保存
        empRewardPunishDO = save(empRewardPunishDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return empRewardPunishDO.to(EmpRewardPunishVO.class);
    }

    @Override
    public Integer onlySave(EmpRewardPunishDO empRewardPunishDO) {
        return empRewardPunishDAO.insert(empRewardPunishDO);
    }

    /**
     * 校验员工和公司
     *
     * @param empId     员工id
     * @param companyId 公司id
     * @param siteId    站点
     */
    private void checkEmpAndCompany(String empId, String companyId, String siteId) {
        ParamException.hasLength(empId, "员工id不能为空");
        ParamException.hasLength(companyId, "公司id不能为空");
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(EmpRewardPunishUpdateDTO empRewardPunishUpdateDTO, TokenUser tokenUser) {
        //转DO
        EmpRewardPunishDO empRewardPunishDO = empRewardPunishUpdateDTO.to(EmpRewardPunishDO.class);
        EmpRewardPunishDO empRewardPunish = selectDOById(empRewardPunishDO.getId(), tokenUser.getSiteId());
        empRewardPunishDO.setCreateUserId(empRewardPunish.getCreateUserId());
        empRewardPunishDO.setGmtCreate(empRewardPunish.getGmtCreate());
        empRewardPunishDO.setGmtModified(new Date());
        empRewardPunishDO.setSiteId(empRewardPunish.getSiteId());
        empRewardPunishDO.setValid(empRewardPunish.getValid());
        empRewardPunishDO.setModifiedUserId(tokenUser.getUserId());
        //根据主键更新，更新非null值
        return updateById(empRewardPunishDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... empRewardPunishIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) empRewardPunishIds);
    }


    @Override
    public EmpRewardPunishVO selectById(String empRewardPunishId, String siteId) {
        EmpRewardPunishDO empRewardPunishDO = selectDOById(empRewardPunishId, siteId);
        if (empRewardPunishDO == null) {
            return null;
        }
        return empRewardPunishDO.to(EmpRewardPunishVO.class);
    }

    @Override
    public List<EmpRewardPunishListVO> select(EmpRewardPunishQuery empRewardPunishQuery, String siteId) {
        List<EmpRewardPunishDO> empRewardPunishDOList = selectDO(empRewardPunishQuery, siteId);
        if(CollectionUtils.isEmpty(empRewardPunishDOList)) {
            return empRewardPunishDOList == null ? null : new ArrayList<>();
        }
        return empRewardPunishDOList.stream()
                .map(empRewardPunishDO -> empRewardPunishDO.to(EmpRewardPunishListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(EmpRewardPunishQuery empRewardPunishQuery, String siteId) {
        Example example = buildExample(empRewardPunishQuery,siteId);
        return empRewardPunishDAO.selectCountByExample(example);
    }

    @Override
    public Page<EmpRewardPunishListVO> selectPage(EmpRewardPunishQuery empRewardPunishQuery, String siteId) {
        Example example = buildExample(empRewardPunishQuery,siteId);
        Page<EmpRewardPunishDO> page = empRewardPunishDAO.selectPageByExample(example,
                empRewardPunishQuery.getPageNo(),
                empRewardPunishQuery.getPageSize());

        return page.to(EmpRewardPunishListVO.class);
    }

    @Override
    public EmpRewardPunishDO selectDOById(String empRewardPunishId, String siteId) {
        return listById(empRewardPunishId, siteId);
    }

    @Override
    public List<EmpRewardPunishDO> selectDO(EmpRewardPunishQuery empRewardPunishQuery, String siteId) {
        Example example = buildExample(empRewardPunishQuery,siteId);
        return empRewardPunishDAO.selectByExample(example);
    }

    @Override
    public List<EmpRewardPunishDO> listByEmpId(String empId, String siteId) {
        Example example = new Example(EmpRewardPunishDO.class);
        example.and()
                .andEqualTo("empId", empId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        return empRewardPunishDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void deleteByCompanyId(String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpRewardPunishDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        // 逻辑删除
        List<EmpRewardPunishDO> list = empRewardPunishDAO.selectByExample(example);
        String[] ids = list.stream()
                .map(BaseDO::getId).toArray(String[]::new);
        deleteByIds(tokenUser, ids);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void publishEmpRewardPunishList(List<EmpRewardPunishDTO> empRewardPunishList, String companyId, String empId, TokenUser tokenUser) {
        // 删除某个员工所有的
        deleteByEmpId(empId, tokenUser);

        if (CollectionUtils.isEmpty(empRewardPunishList)) {
            return;
        }

        empRewardPunishList.forEach(
                empRewardPunishDTO -> {
                    empRewardPunishDTO.setCompanyId(companyId);
                    empRewardPunishDTO.setEmpId(empId);
                    // 新增
                    EmpRewardPunishAddDTO empRewardPunishAddDTO = empRewardPunishDTO.to(EmpRewardPunishAddDTO.class);
                    save(empRewardPunishAddDTO, tokenUser);
                }
        );
    }

    /**
     * 删除某个员工所有的
     *
     * @param empId     员工id
     * @param tokenUser 当前用户
     */
    private void deleteByEmpId(String empId, TokenUser tokenUser) {
        // 逻辑删除
        List<EmpRewardPunishDO> list = listByEmpId(empId, tokenUser.getSiteId());
        String[] ids = list.stream()
                .map(BaseDO::getId).toArray(String[]::new);
        deleteByIds(tokenUser, ids);
    }


    /**
     * 根据查询参数，构建example

     * @param empRewardPunishQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(EmpRewardPunishQuery empRewardPunishQuery, String siteId) {
        Example example = new Example(EmpRewardPunishDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (empRewardPunishQuery.getEmpId() != null) {
            example.and().andEqualTo("empId", empRewardPunishQuery.getEmpId());
        }
        if (empRewardPunishQuery.getRewardPunish() != null) {
            example.and().andEqualTo("rewardPunish", empRewardPunishQuery.getRewardPunish());
        }
        if (empRewardPunishQuery.getRewardType() != null) {
            example.and().andEqualTo("rewardType", empRewardPunishQuery.getRewardType());
        }
        if (empRewardPunishQuery.getPunishType() != null) {
            example.and().andEqualTo("punishType", empRewardPunishQuery.getPunishType());
        }
        if (empRewardPunishQuery.getHandleDateStart() != null &&
                empRewardPunishQuery.getHandleDateEnd() != null) {
            example.and().andBetween("handleDate", empRewardPunishQuery.getHandleDateStart(),
                    empRewardPunishQuery.getHandleDateEnd());
        }
        if (empRewardPunishQuery.getContent() != null) {
            example.and().andEqualTo("content", empRewardPunishQuery.getContent());
        }
        if (empRewardPunishQuery.getAmount() != null) {
            example.and().andEqualTo("amount", empRewardPunishQuery.getAmount());
        }
        if (empRewardPunishQuery.getReason() != null) {
            example.and().andEqualTo("reason", empRewardPunishQuery.getReason());
        }
        if (empRewardPunishQuery.getRemark() != null) {
            example.and().andEqualTo("remark", empRewardPunishQuery.getRemark());
        }
        if (empRewardPunishQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", empRewardPunishQuery.getCompanyId());
        }
        // 排序
        ExampleKit.setExampleOrder(example,empRewardPunishQuery.getOrders());
        return example;
    }
}




